package com.atguigu.spzx.manager.service.impl;

import com.atguigu.spzx.common.utils.BeanUtils;
import com.atguigu.spzx.common.constant.SysMenuStatusEnum;
import com.atguigu.spzx.manager.mapper.SysMenuMapper;
import com.atguigu.spzx.manager.mapper.SysRoleMapper;
import com.atguigu.spzx.manager.mapper.SysRoleMenuMapper;
import com.atguigu.spzx.manager.service.SysRoleService;
import com.atguigu.spzx.manager.entity.SysMenu;
import com.atguigu.spzx.manager.entity.SysRole;
import com.atguigu.spzx.manager.entity.SysRoleMenu;
import com.atguigu.spzx.manager.vo.sysRole.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.atguigu.spzx.manager.modules.utils.MenuHelper;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * SysRoleServiceImpl
 * </p>
 *
 * @author flyduck
 * @since 2023/10/23
 */
@Service
public class SysRoleServiceImpl implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    /**
     * 条件分页查询
     * @param pageParam
     * @param sysRoleQueryReqVo
     * @return
     */
    @Override
    public Page<SysRoleQueryRespVo> getRolePageByQuery(Page<SysRole> pageParam, SysRoleQueryReqVo sysRoleQueryReqVo) {
        Page<SysRoleQueryRespVo> page = sysRoleMapper.getRolePageByQuery(pageParam,sysRoleQueryReqVo);
        return page;
    }

    /**
     * 添加角色
     * @param sysRoleSaveReqVo
     * @return
     */
    @Override
    public void saveRole(SysRoleSaveReqVo sysRoleSaveReqVo) {
        SysRole sysRole = BeanUtils.toBean(sysRoleSaveReqVo, SysRole.class);
        sysRoleMapper.insert(sysRole);
    }

    /**
     * 查询所有角色
     * @return
     */
    @Override
    public List<SysRoleQueryRespVo> getRoleList() {
        List<SysRole> list = sysRoleMapper.selectList(null);
        List<SysRoleQueryRespVo> sysRoleQueryRespVoList = BeanUtils.toBeanList(list, SysRoleQueryRespVo.class);
        return sysRoleQueryRespVoList;
    }

    /**
     * 根据id逻辑删除角色
     * @param id
     * @return
     */
    @Override
    public void deleteRoleById(Long id) {
        sysRoleMapper.deleteById(id);
    }

    /**
     * 根据id查询
     * @param id
     * @return
     */
    @Override
    public SysRoleQueryRespVo getRoleById(Long id) {
        SysRole sysRole = sysRoleMapper.selectById(id);
        SysRoleQueryRespVo sysRoleQueryRespVo = BeanUtils.toBean(sysRole, SysRoleQueryRespVo.class);
        return sysRoleQueryRespVo;
    }

    /**
     * 修改角色
     * @param sysRoleSaveReqVo
     * @return
     */
    @Override
    public void updateRoleById(SysRoleUpdateReqVo sysRoleSaveReqVo) {
        SysRole sysRole = BeanUtils.toBean(sysRoleSaveReqVo, SysRole.class);
        sysRoleMapper.updateById(sysRole);
    }

    /**
     * 批量删除
     * @param ids
     */
    @Override
    public void deleteRoleListByIdList(List<Long> ids) {
        sysRoleMapper.deleteBatchIds(ids);
    }

    /**
     * 根据角色获取菜单权限
     * @param roleId
     * @return
     */
    @Override
    public List<SysRoleAssignMenuQueryVo> getAssignedMenuListByRoleId(Long roleId) {
        //获取所有菜单 status = 1
        List<SysMenu> allMenu = sysMenuMapper.getMenuListByStatus(SysMenuStatusEnum.NORMAL.getCode());
        List<SysRoleAssignMenuQueryVo> allMenuRespVos = BeanUtils.toBeanList(allMenu, SysRoleAssignMenuQueryVo.class);

        //根据角色查询分配过的菜单
        List<SysRoleMenu> sysRoleMenuList = sysRoleMenuMapper.getRoleMenuListByRoleId(roleId);
        Set<Long> menuIdSet = sysRoleMenuList.stream()
                .map(SysRoleMenu::getMenuId)
                .collect(Collectors.toSet());

        //拿着分配的菜单和所有菜单比对，如果包含，则设置isSelect为true
        for (SysRoleAssignMenuQueryVo respVo : allMenuRespVos) {
            if (menuIdSet.contains(respVo.getId())) {
                respVo.setSelect(true);
            }else {
                respVo.setSelect(false);
            }
        }

        //转换成树形结构
        return MenuHelper.buildTree(allMenuRespVos);
    }

    /**
     * 给角色分配菜单权限
     * @param reqVo
     */
    @Override
    public void assignMenuForRole(SysRoleAssignMenuReqVo reqVo) {
        //根据角色id删除菜单权限
        sysRoleMenuMapper.deleteByRoleId(reqVo.getRoleId());

        //获取到菜单id，添加角色菜单关系
        List<Long> menuIdList = reqVo.getMenuIdList();
        sysRoleMenuMapper.insertList(reqVo.getRoleId(),menuIdList);
    }
}
